package com.infomanage.servlet;

import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import jxl.Workbook;
import jxl.write.Label;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import jxl.write.WriteException;
import jxl.write.biff.RowsExceededException;

/**
 * 解析页面并导出为Excel格式。
 * 
 */
public class ExcelExportor extends HttpServlet {

	private static final long serialVersionUID = 8563623076707865788L;

	@Override
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws IOException {
		request.setCharacterEncoding("GBK");
		String content = request.getParameter("c");
		if (content == null) {
			Writer out = response.getWriter();
			response.setCharacterEncoding("GBK");
			out.write("<html><body>No Content</body></html>");
			return;
		}
		try {
			export(content, response);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private WritableWorkbook wwb = null;

	private WritableSheet sheet = null;

	private void export(String content, HttpServletResponse response)
			throws IOException, RowsExceededException, WriteException {
		response.setContentType("application/ms-excel");
		String sheetName = getCaption(content);
		if (sheetName == null) {
			sheetName = "Sheet1";
		}
		sheetName = sheetName.replaceAll(":", "").replaceAll("[)]", "")
				.replaceAll("[(]", "");
		response.addHeader("Content-Disposition", "attachment; filename="
				+ new String(sheetName.getBytes("GBK"), "ISO-8859-1") + ".xls");

		OutputStream os = response.getOutputStream();
		wwb = Workbook.createWorkbook(os);
		wwb.setProtected(true);

		sheet = wwb.createSheet(sheetName, 0);
		int row = 0;
		int col = 0;
		Label label = null;

		if (sheetName.trim().length() > 30) {
			label = new Label(col, row, sheetName);
			sheet.addCell(label);
			row++;
		}

		List<TD> listBody = getContent(content);
		Map<String, Boolean> map = new HashMap<String, Boolean>();
		for (TD td : listBody) {
			if (td == null) {
				row++;
				col = 0;
				continue;
			}

			while (map.get(col + "-" + row) != null) {
				col++;
			}

			if (td.colspan > 1 || td.rowspan > 1) {
				sheet.mergeCells(col, row, col + td.colspan - 1, row
						+ td.rowspan - 1);
				for (int i = col; i <= col + td.colspan - 1; i++) {
					for (int j = row; j <= row + td.rowspan - 1; j++) {
						map.put(i + "-" + j, true);
					}
				}
			}

			label = new Label(col, row, td.content);
			sheet.addCell(label);

			map.put(col + "-" + row, true);
			col += td.colspan;
		}
		wwb.write();
		wwb.close();
	}

	private String getCaption(String content) {
		int begin = content.indexOf("<CAPTION>");
		int end = content.indexOf("</CAPTION>");
		if (begin == -1 || end == -1) {
			return null;
		}
		begin = content.indexOf(">", begin);
		if (begin == -1) {
			return null;
		}
		return content.substring(begin + 1, end);
	}

	private List<TD> getContent(String content)
			throws UnsupportedEncodingException {
		int begin = -1;
		int end = -1;
		int index = -1;
		String numberStr;
		int number;
		String[] tables = content.split("</TABLE>");
		List<TD> list = new ArrayList<TD>();
		for (String table : tables) {
			String[] trs = table.split("</TR>");
			for (String tr : trs) {
				number = 1;
				String[] ss = tr.split("</TD>");
				for (String s : ss) {
					begin = s.indexOf("<TD>");
					TD td = new TD();
					begin = s.indexOf("rowSpan=");
					if (begin != -1) {
						end = s.indexOf(" ", begin);

						if (end == -1) {
							end = index;
						}
						numberStr = s.substring(begin + 8, end).replace('"',
								' ').replace('\'', ' ').trim();
						number = Integer.parseInt(numberStr);
						td.rowspan = number;
					}

					begin = s.indexOf("colSpan=");
					if (begin != -1) {
						end = s.indexOf(" ", begin);
						index = s.indexOf(">", begin);
						if (end == -1) {
							end = index;
						}
						if (end > index) {
							end = index;
						}
						numberStr = s.substring(begin + 8, end).replace('"',
								' ').replace('\'', ' ').trim();
						number = Integer.parseInt(numberStr);
						td.colspan = number;
					}
					td.content = s.substring(index + 1).replaceAll("\\<.*?\\>",
							"").replaceAll(" ", "").trim();
					list.add(td);
				}
				list.add(null);
			}
			list.add(null);
			list.add(null);
		}
		return list;
	}

	class TD {
		int rowspan = 1;

		int colspan = 1;

		String content;
	}
}
